package com.tender.integration.websocket.utils;

import com.tender.enums.DeviceEnum;
import com.tender.integration.websocket.pojo.WebSocketWrapperInfo;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public class WebSocketMapUtil {

    // 线程安全
    private static final Map<String, Map<String, WebSocketWrapperInfo>> CLIENTS_MAP = new ConcurrentHashMap<>();

    public static Collection<Map<String, WebSocketWrapperInfo>> values() {
        return CLIENTS_MAP.values();
    }

    /**
     * 根据 userId 获取
     */
    public static Map<String, WebSocketWrapperInfo> getByUserId(String userId) {
        return CLIENTS_MAP.get(userId);
    }

    /**
     * 根据 userId 和 device 获取
     */
    public static WebSocketWrapperInfo getByUserIdAndDevice(String userId, String device) {
        Map<String, WebSocketWrapperInfo> webSocketInfoMap = CLIENTS_MAP.get(userId);
        if (null != webSocketInfoMap) {
            return webSocketInfoMap.get(device);
        }

        return null;
    }

    /**
     * 根据 userId 和 device 删除
     */
    public static Boolean deleteByUserIdAndDevice(String userid, String device) {
        Map<String, WebSocketWrapperInfo> webSocketInfoMap = CLIENTS_MAP.get(userid);
        if (null != webSocketInfoMap) {
            return null != webSocketInfoMap.remove(device);
        }

        return false;
    }



    public static void putMap(String userId, WebSocketWrapperInfo webSocketWrapperInfo, String device) {
        Map<String, WebSocketWrapperInfo> webSocketMap = getByUserId(userId);
        if (null == webSocketMap) {
            webSocketMap = new ConcurrentHashMap<>(16);
        }
        webSocketMap.put(device, webSocketWrapperInfo);
        CLIENTS_MAP.put(String.valueOf(userId), webSocketMap);
    }

    /**
     * 当前 JVM 上有多少个用户
     */
    public static Integer getUserNum() {
        return CLIENTS_MAP.size();
    }

    public static Integer getPcUserNum() {
        if (getUserNum() > 0) {
            return calculateSum(DeviceEnum.PC);
        }

        return 0;
    }

    public static Integer getIpadUserNum() {
        if (getUserNum() > 0) {
            return calculateSum(DeviceEnum.IPAD);
        }

        return 0;
    }

    public static Integer getAppUserNum() {
        if (getUserNum() > 0) {
            return calculateSum(DeviceEnum.APP);
        }

        return 0;
    }

    private static Integer calculateSum(DeviceEnum deviceEnum) {
        List<Integer> list = new ArrayList<>();
        CLIENTS_MAP.forEach((userId, deviceMap) -> {
            if (deviceMap.containsKey(deviceEnum.getDeviceType())) {
                list.add(1);
            }
        });
        return list.stream().reduce(0, Integer::sum);
    }

}
